using System;
using System.Linq;
using HashFoo.NhibTests.DomainFixtures.Enumerations;
using HashFoo.NhibTests.DomainFixtures.Models;
using HashFoo.SqlServer.Spatial;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NHibernate.Linq;

namespace HashFoo.NhibTests
{
    [TestClass]
    public class LinqCapabilityTests
    {
        [TestMethod]
        [Description("Tests that custom DTOs can be mapped in the query")]
        public void custom_dto_in_select_peforms_sever_side_projection()
        {
            Helpers.NukeDatabase();

            var migrationManager = Helpers.CreateDefaultMigrationManagerWorker();
            migrationManager.Create();

            var grower = new Grower
            {
                Name = "Bob",
                FarmCount = 1,
                FieldCount = 20
            };

            // get session and create some field boundaries!!!
            using (var sessionFactory = DomainFixtures.MockConfigurator.DefaultConfiguration.BuildSessionFactory())
            using (var session = sessionFactory.OpenSession())
            {
                session.Save(grower);

                session.Flush();
                session.Clear();

                Assert.IsTrue(session.Query<Grower>().Count() > 0);

                var actualField = session.Query<Grower>()
                    .Where(g => g.FarmCount > 0 && g.FieldCount > 0)
                    .Select(fb => new GrowerDto { Id = fb.Id, Name = fb.Name})
                    .OrderBy(dto => dto.Name)
                    .Where(dto => dto.Id != Guid.Empty)
                    .Skip(0)
                    .Take(10);


                Assert.IsNotNull(actualField.ToArray());
                Assert.AreEqual(1, actualField.Count());

                //Assert.IsTrue(actualField.FieldType.Value == FieldType.Corn.Value);

                session.Close();
                sessionFactory.Close();
            }
        }

        [TestMethod]
        public void can_query_by_enum()
        {
            Helpers.NukeDatabase();

            var migrationManager = Helpers.CreateDefaultMigrationManagerWorker();
            migrationManager.Create();

            var grower = new Grower
            {
                Name = "Bob",
                FarmCount = 1,
                FieldCount = 20,
                GrowerType = GrowerType.Hillbilly
            };

            // get session and create some field boundaries!!!
            using (var sessionFactory = DomainFixtures.MockConfigurator.DefaultConfiguration.BuildSessionFactory())
            using (var session = sessionFactory.OpenSession())
            {
                session.Save(grower);

                session.Flush();
                session.Clear();

                Assert.IsTrue(session.Query<Grower>().Count() > 0);

                var actualField = session.Query<Grower>()
                    .Where(g => g.FarmCount > 0 && g.FieldCount > 0)
                    .Select(fb => new GrowerDto { Id = fb.Id, Name = fb.Name, GrowerType = fb.GrowerType })
                    .OrderBy(dto => dto.Name)
                    .Where(dto => dto.Id != Guid.Empty && dto.GrowerType == GrowerType.Hillbilly)
                    .Skip(0)
                    .Take(10);


                Assert.IsNotNull(actualField.ToArray());
                Assert.AreEqual(1, actualField.Count());

                //Assert.IsTrue(actualField.FieldType.Value == FieldType.Corn.Value);

                session.Close();
                sessionFactory.Close();
            }
        }

        [TestMethod]
        public void can_query_by_enumeration_class()
        {
            Helpers.NukeDatabase();

            var migrationManager = Helpers.CreateDefaultMigrationManagerWorker();
            migrationManager.Create();

            var field = new FieldBoundary
            {
                Boundary = Geography.CreateSquarePolygon(5, 5, 10, 10),
                FieldType = FieldType.Corn
            };

            // get session and create some field boundaries!!!
            using (var sessionFactory = DomainFixtures.MockConfigurator.DefaultConfiguration.BuildSessionFactory())
            using (var session = sessionFactory.OpenSession())
            {
                session.Save(field);

                session.Flush();
                session.Clear();

                Assert.IsTrue(session.Query<FieldBoundary>().Count() > 0);

                var actualField = session.Query<FieldBoundary>().Where(f => f.FieldType == FieldType.Corn);


                Assert.IsNotNull(actualField.ToArray());
                Assert.AreEqual(1, actualField.Count());

                //Assert.IsTrue(actualField.FieldType.Value == FieldType.Corn.Value);

                session.Close();
                sessionFactory.Close();
            }
        }
    }

    public class GrowerDto
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
        public GrowerType GrowerType { get; set; }
    }
}